home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Examples / Shark Attack / Sources & Headers / Shark Attack.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  13.1 KB  |  481 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // Shark Attack.c
  3. //
  4. // Created 7/25/96
  5. ///--------------------------------------------------------------------------------------
  6.  
  7.  
  8. #include <SWIncludes.h>
  9. #include <SWGameUtils.h>
  10. #include <SWApplication.h>
  11.  
  12. #include "Application.h"
  13. #include "Shark Attack.h"
  14. #include "Level.h"
  15. #include "NewSprite.h"
  16. #include "MyUtils.h"
  17. #include "Special Effects.h"
  18. #include "Stats.h"
  19.  
  20.  
  21. #define kMaxFPS                    45            // Keep the animation from going too fast
  22.  
  23. #define kMaxSpriteWorldWidth    640            // Max size of the SpriteWorld. Helps avoid
  24. #define kMaxSpriteWorldHeight    480            // running out of memory on large monitors.
  25.  
  26.  
  27. /***********/
  28. /* Globals */
  29. /***********/
  30.  
  31. SpriteWorldPtr    gSpriteWorldP;
  32. FramePtr         gStatsWindowFrameP;
  33. FramePtr         gStatsBackFrameP;
  34. FramePtr         gStatsNumberFrameP;
  35. SpriteLayerPtr    gSubSpriteLayerP;
  36. SpriteLayerPtr    gBulletSpriteLayerP;
  37. SpriteLayerPtr    gFishSpriteLayerP;
  38. SpriteLayerPtr    gSharkSpriteLayerP;
  39. WindowPtr        gWindowP;
  40. RgnHandle        gOrigWindRgn;         // Original region for the window
  41. RgnHandle        gPixPatWindRgn;        // Temporary region for drawing the background pixPat
  42. RgnHandle        gTempRgn;            // Temporary region used by the FishHitDrawProc
  43.  
  44. DrawProcPtr        gScreenDrawProc;
  45. DrawProcPtr        gSpriteMaskDrawProc;
  46. KeyStruct        gKeys;
  47.  
  48. PixPatHandle    gBackgroundPixPatH;
  49. PixPatHandle    gTitleWaterPixPatH;
  50. PicHandle        gGameWaterPictH;
  51.  
  52. short            gFishDelay = 0;
  53. short            gSharkDelay = 0;
  54. short            gNumFishOnScreen = 0;
  55. short            gNumSharksOnScreen = 0;
  56. SpritePtr        gLastBulletP;            // Pointer to the most recently shot bullet. Kept
  57.                                         // so we can update the stereo sound as it moves.
  58. SpritePtr        gSubCloneP = NULL;        // Pointer to the sub sprite that is added
  59.                                         // to the animation. Used by SharkSpriteMoveProc
  60.  
  61. Boolean            gGameOver;
  62. Boolean            gGameIsPaused;
  63. long            gScore;
  64. long            gNextLevelScore;        // When score equals this, advance to next level
  65. short            gCurrentLevel;
  66. short            gNumLivesLeft;
  67. short            gNumShellsNeeded;
  68. Boolean            gSubIsStillOnScreen;
  69.  
  70.  
  71. ///--------------------------------------------------------------------------------------
  72. // SetUpSpriteWorld
  73. ///--------------------------------------------------------------------------------------
  74.  
  75. void    SetUpSpriteWorld( void )
  76. {
  77.     Rect            worldRect;
  78.     OSErr            err;
  79.  
  80.     
  81.     err = SWEnterSpriteWorld();
  82.     FatalError(err);
  83.     
  84.     worldRect = gWindowP->portRect;
  85.     
  86.     if (worldRect.right > kMaxSpriteWorldWidth)
  87.         worldRect.right = kMaxSpriteWorldWidth;
  88.     if (worldRect.bottom > kMaxSpriteWorldHeight)
  89.         worldRect.bottom = kMaxSpriteWorldHeight;
  90.     
  91.     CenterRect(&worldRect, &gWindowP->portRect);
  92.     err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP, 
  93.             &worldRect, NULL, 0);
  94.     FatalError(err);
  95.     
  96.     
  97.         // Create the sprite layers
  98.     err = SWCreateSpriteLayer(&gSubSpriteLayerP);
  99.     FatalError(err);
  100.     
  101.     err = SWCreateSpriteLayer(&gBulletSpriteLayerP);
  102.     FatalError(err);
  103.     
  104.     err = SWCreateSpriteLayer(&gFishSpriteLayerP);
  105.     FatalError(err);
  106.     
  107.     err = SWCreateSpriteLayer(&gSharkSpriteLayerP);
  108.     FatalError(err);
  109.     
  110.     SWAddSpriteLayer(gSpriteWorldP, gFishSpriteLayerP);        // Bottom layer
  111.     SWAddSpriteLayer(gSpriteWorldP, gSharkSpriteLayerP);    // Middle layer
  112.     SWAddSpriteLayer(gSpriteWorldP, gBulletSpriteLayerP);    // Middle layer
  113.     SWAddSpriteLayer(gSpriteWorldP, gSubSpriteLayerP);        // Top layer
  114.     
  115.     SWLockSpriteWorld(gSpriteWorldP);
  116.     
  117.     
  118.         // Draw a nice background
  119.     SWSetPortToBackground(gSpriteWorldP);
  120.     FillCRect(&gSpriteWorldP->backRect, gTitleWaterPixPatH);
  121.     
  122.     
  123.         // Set up the various drawProcs
  124.     gScreenDrawProc = SWStdWorldDrawProc;
  125.     gSpriteMaskDrawProc = SWStdSpriteDrawProc;
  126.     
  127.     if (gSpriteWorldP->pixelDepth >= 8)        // 8-bit, 16-bit, and 32-bit blitter
  128.     {
  129.         gSpriteMaskDrawProc = BlitPixieCompiledSpriteDrawProc;
  130.         gScreenDrawProc = BlitPixieRectDrawProc;
  131.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieRectDrawProc);
  132.     }
  133.     else if ( SW_68K )        // Use 68k-only AllBit blitter when in depths lower than 8-bits
  134.     {
  135.         gSpriteMaskDrawProc = BlitPixieAllBitMaskDrawProc;
  136.         gScreenDrawProc = BlitPixieAllBitRectDrawProc;
  137.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  138.     }
  139.     
  140.     SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
  141. }
  142.  
  143.  
  144. ///--------------------------------------------------------------------------------------
  145. // NewGame - called when the user selects "New Game" from the File Menu.
  146. ///--------------------------------------------------------------------------------------
  147.  
  148. void    NewGame( void )
  149. {
  150.     PrepareGame();
  151.     RunGame();
  152.     CleanUpAfterGame();
  153. }
  154.  
  155.  
  156. ///--------------------------------------------------------------------------------------
  157. // PrepareGame
  158. ///--------------------------------------------------------------------------------------
  159.  
  160. void    PrepareGame( void )
  161. {
  162.     Rect    worldRect;
  163.     
  164.     gLastBulletP = NULL;
  165.     gGameOver = false;
  166.     gCurrentLevel = 1;
  167.     gNumLivesLeft = 3;
  168.     gNumShellsNeeded = 10;
  169.     gScore = 0;
  170.     gNextLevelScore = kAdvanceLevelScore;
  171.     
  172.     ResetStats();
  173.     HideCursor();
  174.     EraseMenuBar();
  175.     
  176.         // We can draw directly to the screen now
  177.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
  178.     
  179.         // Remove sprites from title screen animation
  180.     RemoveAllSprites(gSpriteWorldP);
  181.  
  182.         // Make the SpriteWorld think it's smaller, to make room for the stats area
  183.     worldRect = gSpriteWorldP->windRect;
  184.     worldRect.top += kStatsHeight;
  185.     SWChangeWorldRect(gSpriteWorldP, &worldRect, true);
  186.     
  187.         // Draw the game background
  188.     FillBackgroundWithPict(gSpriteWorldP, gGameWaterPictH);
  189.     
  190.     SetUpLevel();
  191.     SWUpdateSpriteWorld(gSpriteWorldP, false);
  192.     WipeWindow(gSpriteWorldP);
  193.     
  194.         // Draw the stats area
  195.     UpdateStatsArea();
  196. }
  197.  
  198.  
  199. ///--------------------------------------------------------------------------------------
  200. // EraseMenuBar - hide menu bar and draw background pixpat in its place, if necessary.
  201. ///--------------------------------------------------------------------------------------
  202.  
  203. void    EraseMenuBar( void )
  204. {
  205.     RgnHandle mBarRgn;
  206.     
  207.     SetPort(gWindowP);
  208.     mBarRgn = SWHideMenuBar(gWindowP);
  209.     
  210.         // mBarRgn = mBarRgn & gPixPatWindRgn
  211.     SectRgn(mBarRgn, gPixPatWindRgn, mBarRgn);
  212.     
  213.     SetClip(mBarRgn);
  214.     FillCRect(&gWindowP->portRect, gBackgroundPixPatH);
  215.     SetClip(gOrigWindRgn);
  216. }
  217.  
  218.  
  219. ///--------------------------------------------------------------------------------------
  220. // RunGame
  221. ///--------------------------------------------------------------------------------------
  222.  
  223. void    RunGame( void )
  224. {
  225.     FatalError( SWStickyError() ); // Make sure no errors got past us during setup
  226.  
  227.     while (!gGameOver)
  228.     {
  229.         SWProcessSpriteWorld(gSpriteWorldP);
  230.         
  231.             // Check for collisions with the fish and bullets
  232.         SWCollideSpriteLayer(gSpriteWorldP, gFishSpriteLayerP, gBulletSpriteLayerP);
  233.         SWCollideSpriteLayer(gSpriteWorldP, gSharkSpriteLayerP, gBulletSpriteLayerP);
  234.  
  235.             // Make sure no errors occurred during a MoveProc, etc.
  236.         FatalError( SWStickyError() );
  237.         
  238.         SWAnimateSpriteWorld(gSpriteWorldP);
  239.         
  240.         if (gSpriteWorldP->frameHasOccurred)
  241.             ProcessLevel();
  242.         
  243.             // Check for collisions with the submarine and fish
  244.         SWCollideSpriteLayer(gSpriteWorldP, gSubSpriteLayerP, gFishSpriteLayerP);
  245.         SWCollideSpriteLayer(gSpriteWorldP, gSubSpriteLayerP, gSharkSpriteLayerP);
  246.         
  247.         UpdateKeys();    // Read any new keyUp/keyDown events
  248.         UpdateStatsNumbers();
  249.         
  250.             // Time to advance the level?
  251.         if (gScore > gNextLevelScore && gNumFishOnScreen <= 0 && gNumSharksOnScreen <= 0)
  252.             AdvanceLevel();
  253.     }
  254. }
  255.  
  256.  
  257. ///--------------------------------------------------------------------------------------
  258. // CleanUpAfterGame
  259. ///--------------------------------------------------------------------------------------
  260.  
  261. void    CleanUpAfterGame( void )
  262. {
  263.         // Remove any sprites that are left
  264.     RemoveAllSprites(gSpriteWorldP);
  265.     
  266.         // Restore the SpriteWorld to its normal size
  267.     SWRestoreWorldRect(gSpriteWorldP);
  268.     
  269.         // Draw the normal background pattern
  270.     SWSetPortToBackground(gSpriteWorldP);
  271.     FillCRect(&gSpriteWorldP->backRect, gTitleWaterPixPatH);
  272.     
  273.     AddTitleSprite();
  274.     SWUpdateSpriteWorld(gSpriteWorldP, false);
  275.     WipeWindow(gSpriteWorldP);
  276.     
  277.         // Don't draw directly to the screen during the title screen animation
  278.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, SWStdWorldDrawProc);
  279.     
  280.     gFishDelay = 0;
  281.     gSharkDelay = 0;
  282.  
  283.     
  284.     SWShowMenuBar(gWindowP);
  285.     InitCursor();
  286. }
  287.  
  288.  
  289. ///--------------------------------------------------------------------------------------
  290. // RemoveAllSprites - Remove and dispose all sprites in the SpriteWorld
  291. ///--------------------------------------------------------------------------------------
  292.  
  293. void    RemoveAllSprites(SpriteWorldPtr spriteWorldP)
  294. {
  295.     SpriteLayerPtr    curSpriteLayerP;
  296.     SpritePtr        curSpriteP, nextSpriteP;
  297.     
  298.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  299.     
  300.         // iterate through the layers in the world
  301.     while (curSpriteLayerP != NULL)
  302.     {
  303.         curSpriteP = curSpriteLayerP->headSpriteP;
  304.         
  305.             // iterate through the sprites in this layer
  306.         while (curSpriteP != NULL)
  307.         {            
  308.             nextSpriteP = curSpriteP->nextSpriteP;
  309.             
  310.             SWRemoveSprite(curSpriteP);
  311.             SWDisposeSprite(&curSpriteP);
  312.             
  313.             curSpriteP = nextSpriteP;
  314.         }
  315.         
  316.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  317.     }
  318.     
  319.     gNumFishOnScreen = 0;
  320.     gNumSharksOnScreen = 0;
  321.     gLastBulletP = NULL;
  322. }
  323.  
  324.  
  325. ///--------------------------------------------------------------------------------------
  326. // PauseSprites - Pause all layers but the sub layer
  327. ///--------------------------------------------------------------------------------------
  328.  
  329. void    PauseSprites()
  330. {
  331.     SWPauseSpriteLayer(gBulletSpriteLayerP);
  332.     SWPauseSpriteLayer(gFishSpriteLayerP);
  333.     SWPauseSpriteLayer(gSharkSpriteLayerP);
  334. }
  335.  
  336.  
  337. ///--------------------------------------------------------------------------------------
  338. // UnpauseSprites - unpause all layers but the sub layer
  339. ///--------------------------------------------------------------------------------------
  340.  
  341. void    UnpauseSprites()
  342. {
  343.     SWUnpauseSpriteLayer(gBulletSpriteLayerP);
  344.     SWUnpauseSpriteLayer(gFishSpriteLayerP);
  345.     SWUnpauseSpriteLayer(gSharkSpriteLayerP);
  346. }
  347.  
  348.  
  349. ///--------------------------------------------------------------------------------------
  350. // CountNumSpritesOnScreen - returns how many Sprites are currently on the screen
  351. ///--------------------------------------------------------------------------------------
  352.  
  353. short    CountNumSpritesOnScreen(SpriteWorldPtr spriteWorldP)
  354. {
  355.     SpriteLayerPtr    curSpriteLayerP;
  356.     short                numSprites = 0;
  357.     
  358.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  359.     
  360.         // iterate through the layers in the world
  361.     while (curSpriteLayerP != NULL)
  362.     {
  363.         numSprites += SWCountNumSpritesInLayer(curSpriteLayerP);
  364.         
  365.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  366.     }
  367.     
  368.     return numSprites;
  369. }
  370.  
  371.  
  372. ///--------------------------------------------------------------------------------------
  373. //  UpdateKeys (Put the latest key values in the gKeys structure)
  374. ///--------------------------------------------------------------------------------------
  375.  
  376. void    UpdateKeys( void )
  377. {
  378.     EventRecord        event;
  379.     short            theChar;
  380.     
  381.     do
  382.     {
  383.         GetOSEvent( (keyUpMask | keyDownMask), &event );
  384.         ProcessKeyEvent(&event);
  385.         
  386.             // Check for shift key
  387.         if (event.modifiers & shiftKey)
  388.             gKeys.shift = true;
  389.         else
  390.             gKeys.shift = false;
  391.         
  392.             // Check for Command key combinations
  393.         if ((event.modifiers & cmdKey) && (event.what == keyDown))
  394.         {
  395.             theChar = event.message & charCodeMask;
  396.             
  397.             if (theChar == 'p')
  398.                 PauseGame();
  399.             else if (theChar == 'e')
  400.                 gGameOver = true;
  401.             else if (theChar == 'q')
  402.                 ExitSharkAttack();
  403.         }
  404.         
  405.     } while (event.what != nullEvent);
  406. }
  407.  
  408.  
  409. ///--------------------------------------------------------------------------------------
  410. // ProcessKeyEvent
  411. ///--------------------------------------------------------------------------------------
  412.  
  413. void    ProcessKeyEvent( EventRecord *eventP )
  414. {
  415.     short            theKey;
  416.     Boolean            keyState;
  417.     
  418.     if (eventP->what == keyUp || eventP->what == keyDown)
  419.     {
  420.         theKey = (eventP->message & keyCodeMask) >> 8;
  421.         keyState = (eventP->what == keyDown);
  422.         
  423.         if ( (theKey == kLeftArrowKey) || (theKey == kLeftKeyPad) )
  424.             gKeys.left = keyState;
  425.         if ( (theKey == kRightArrowKey) || (theKey == kRightKeyPad) )
  426.             gKeys.right = keyState;
  427.         if ( (theKey == kDownArrowKey) || (theKey == kDownKeyPad) )
  428.             gKeys.down = keyState;
  429.         if ( (theKey == kUpArrowKey) || (theKey == kUpKeyPad) )
  430.             gKeys.up = keyState;
  431.         if (theKey == kShootKeyPad)
  432.             gKeys.shoot = keyState;
  433.         if (theKey == kEscKey && eventP->what == keyDown)
  434.             gGameOver = true;
  435.     }
  436. }
  437.  
  438.  
  439. ///--------------------------------------------------------------------------------------
  440. // PauseGame
  441. ///--------------------------------------------------------------------------------------
  442.  
  443. void    PauseGame( void )
  444. {
  445.     MenuHandle        fileMenuH;
  446.     
  447.     fileMenuH = GetMenuHandle(mFile);
  448.     CheckItem(fileMenuH, iPauseGame, true);
  449.     EnableItem(fileMenuH, iPauseGame);
  450.     EnableItem(fileMenuH, iEndGame);
  451.     DisableItem(fileMenuH, iNewGame);
  452.     
  453.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, SWStdWorldDrawProc);
  454.     SWSetPortToWorkArea(gSpriteWorldP);
  455.     ForeColor(redColor);
  456.     DrawTextInWorkArea("\pPaused", 64);
  457.     SWUpdateWindow(gSpriteWorldP);
  458.     
  459.     HiliteMenu( 0 );
  460.     SWShowMenuBar(gWindowP);
  461.     InitCursor();
  462.     
  463.     gGameIsPaused = true;
  464.     
  465.     while (gGameIsPaused)
  466.         ProcessEvents();
  467.     
  468.     CheckItem(fileMenuH, iPauseGame, false);
  469.     DisableItem(fileMenuH, iPauseGame);
  470.     DisableItem(fileMenuH, iEndGame);
  471.     EnableItem(fileMenuH, iNewGame);
  472.     
  473.     EraseMenuBar();
  474.     HideCursor();
  475.     UpdateStatsArea();
  476.     SWUpdateSpriteWorld(gSpriteWorldP, true);
  477.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
  478. }
  479.  
  480.  
  481.